#include "Eleccion.h"
#include "Utils.h"
#include <sstream>

using namespace Entidades;

Eleccion::Eleccion() {
	this->distritos = new vector<Distrito*> ();
	this->cargo = new Cargo();
}

Eleccion::Eleccion(Eleccion* eleccion) {
	this->distritos = new vector<Distrito*> ();
	this->cargo = new Cargo();

	this->fecha = eleccion->getFecha();
	this->cargo->setNombre(eleccion->getCargo()->getNombre());

	for (unsigned int i = 0; i < eleccion->getDistritos()->size(); i++) {
		this->agregarDistrito(eleccion->getDistritos()->at(i)->getNombre());
	}
}

Cargo *Eleccion::getCargo() const {
	return cargo;
}

vector<Distrito*>* Eleccion::getDistritos() const {
	return distritos;
}

int Eleccion::getFecha() const {
	return fecha;
}

void Eleccion::setCargo(string nombreDelCargo) {
	this->cargo->setNombre(nombreDelCargo);
}

void Eleccion::setFecha(int fecha) {
	this->fecha = fecha;
}

void Eleccion::agregarDistrito(string nombreDistrito) {
	Distrito* distrito = new Distrito();
	distrito->setNombre(nombreDistrito);
	this->distritos->push_back(distrito);
}

void Eleccion::removerDistrito(string nombreDistrito) {
	for (unsigned int i = 0; i < distritos->size(); i++) {
		if (distritos->at(i)->getNombre() == nombreDistrito)
			distritos->erase(distritos->begin() + i);
	}
}

void Eleccion::hidratarse(char* buffer, unsigned int tamanioDelBuffer) {

	//escribo el buffer en el stringStream
	stringstream* ss = new stringstream(stringstream::in | stringstream::out | stringstream::binary);
	ss->seekg(0, ios::beg);
	ss->write(buffer, tamanioDelBuffer);

	//fecha
	ss->read((char*) &(this->fecha), sizeof(int));

	//Cargo (string cargoPrincipal)
	this->setCargo(Utils::ObtenerSiguienteStringVariable(ss));

	//Distritos (int cantidadDeDistritos | string nombre)
	unsigned int cantidadDeDistritos = 0;
	ss->read((char*) &(cantidadDeDistritos), sizeof(int));
	for (unsigned int i = 0; i < cantidadDeDistritos; i++) {
		this->agregarDistrito(Utils::ObtenerSiguienteStringVariable(ss));
	}

	delete ss;
}

char* Eleccion::construirBuffer() {

	//agrupo los atributos
	stringstream* ss = new stringstream(stringstream::in | stringstream::out | stringstream::binary);
	ss->seekp(0, ios::end);

	//fecha
	ss->write((char*) &(this->fecha), sizeof(int));

	//Cargo (string cargoPrincipal)
	unsigned int tamanioDelCargo = this->cargo->getNombre().size();
	ss->write((char*) &tamanioDelCargo, sizeof(int));
	ss->write(this->cargo->getNombre().c_str(), tamanioDelCargo);

	//Distrito (int cantidadDeDistritos | string nombre)
	unsigned int cantidadDeDistritos = distritos->size();
	ss->write((char*) &(cantidadDeDistritos), sizeof(int));
	unsigned int* tamanioDeLaClaveDeDistrito = new unsigned int(0);
	for (unsigned int i = 0; i < cantidadDeDistritos; i++) {
		*tamanioDeLaClaveDeDistrito = distritos->at(i)->getNombre().size();
		ss->write((char*) tamanioDeLaClaveDeDistrito, sizeof(int));
		ss->write(distritos->at(i)->getNombre().c_str(), *tamanioDeLaClaveDeDistrito);
	}
	delete tamanioDeLaClaveDeDistrito;

	//construyo el buffer
	unsigned int tamanioDelBuffer = this->getTamanioDelBuffer();
	char* buffer = new char[tamanioDelBuffer];
	ss->read(buffer, tamanioDelBuffer);
	delete ss;

	//lo devuelvo
	return buffer;
}

unsigned int Eleccion::getTamanioDelBuffer() {

	unsigned int distritosSize = 0;
	for (unsigned int i = 0; i < this->distritos->size(); i++) {
		distritosSize += sizeof(int) + this->distritos->at(i)->getNombre().size();
	}

	return (3 * sizeof(int)) + cargo->getNombre().size() + distritosSize;
}

void Eleccion::marcarComoBorrado() {

	//fecha = 0 | cargo = ""
	this->fecha = 0;
	this->cargo->setNombre("");
}

Eleccion::~Eleccion() {

	for (unsigned int i = 0; i < this->distritos->size(); i++) {
		delete this->distritos->at(i);
	}

	delete this->distritos;
	delete this->cargo;
}

